home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Source.bin / TabPanel.java < prev    next >
Text File  |  1998-08-21  |  21KB  |  683 lines

  1. /*
  2.  Copyright (c) 1995, 1996 Connect! Corporation, Inc. All Rights Reserved.
  3.  Source code usage restricted as defined in Connect! Widgets License Agreement
  4. */
  5.  
  6. package symantec.itools.awt;
  7.  
  8. import java.awt.*;
  9. import java.util.Vector;
  10. import java.lang.Boolean;
  11. import java.beans.PropertyVetoException;
  12. import java.beans.PropertyChangeListener;
  13. import java.beans.VetoableChangeListener;
  14. import java.beans.PropertyChangeEvent;
  15.  
  16.  
  17. //    01/29/97    RKM    Integrated Tim's changes to preserve the current index
  18. //    05/30/97    LAB    Updated to support Java 1.1
  19. //    06/01/97    RKM    Changed symantec.beans references to java.beans
  20. //    07/22/97    LAB    Updated preferredSize and minimumSize to getPreferredSize and getMinimumSize.
  21. //  07/25/97    CAR marked fields transient as needed
  22. //                  innerclasses implement java.io.Serializable
  23. //    08/21/97    RKM    Used setSuppressRepaints in adding of components
  24. //  08/28/97    CAR add(Component, int) now uses the specified index position to place the new tab
  25. //  08/29/97    CAR modified getPreferredSize and getMinimumSize
  26.  
  27. /**
  28.  * TabPanel is a Panel extension which provides for a tabbed dialog effect.
  29.  * Along the top (by default) of the panel is a series of file folder-like tabs,
  30.  * each with a text label. Each tab is associated with a panel or component
  31.  * that gets shown when the user clicks on the tab.
  32.  * The TabPanel automatically manages swapping panels when a tab selected.
  33.  * It can be used directly or extended.
  34.  * When extending from TabPanel be sure to super()
  35.  * during construction and to super.handleEvent(evt) from
  36.  * handleEvent if you override it.
  37.  *
  38.  * @author Scott Fauerbach
  39.  */
  40. public class TabPanel extends BaseTabbedPanel implements java.io.Serializable
  41. {
  42.     /**
  43.      * Constructs a TabPanel with tabs on top, rounded
  44.      */
  45.     public TabPanel()
  46.     {
  47.         this(TOP, ROUNDED);
  48.     }
  49.  
  50.     /**
  51.      * Obsolete. Use TabPanel(int tabsPostion, int tabsStyle).
  52.      */
  53.      // @see symantec.itools.awt.TabPanel#TabPanel(int, int)
  54.     public TabPanel(boolean bTabsOnTop)
  55.     {
  56.         this(bTabsOnTop ? TOP : BOTTOM, bTabsOnTop ? ROUNDED : SQUARE);
  57.     }
  58.  
  59.     /**
  60.      * Constructs a TabPanel with the tabs in the given position and
  61.      * having the specified look.
  62.      * Note that if the tabs are on top, then they always are rounded.
  63.      * @param tabsPosition a constant indicating TOP or BOTTOM
  64.      * @param tabsStyle a constant indicating ROUNDED or SQUARE
  65.      * @see symantec.itools.awt.BaseTabbedPanel#TOP
  66.      * @see symantec.itools.awt.BaseTabbedPanel#BOTTOM
  67.      * @see symantec.itools.awt.BaseTabbedPanel#ROUNDED
  68.      * @see symantec.itools.awt.BaseTabbedPanel#SQUARE
  69.      */
  70.     public TabPanel(int tabsPostion, int tabsStyle)
  71.     {
  72.         super(tabsPostion, tabsStyle);
  73.         vPanels = new Vector();
  74.         String sOS = System.getProperty("os.name");
  75.         if (sOS.equals("Windows 95"))
  76.             bOsHack = true;
  77.         else
  78.             bOsHack = false;
  79.  
  80.         super.addCurrentTabListener(myPropertyChangeHandler);
  81.     }
  82.  
  83.     /**
  84.      * Returns the zero-relative index of the currently selected panel.
  85.      * @return the currently selected panel or -1 if none are shown
  86.      * @see #setCurrentPanelNdx
  87.      */
  88.     public int getCurrentPanelNdx()
  89.     {
  90.         return curIndex;
  91.     }
  92.  
  93.     /**
  94.      * Selects the specified tab and shows its associated panel.
  95.      * @param index the zero-relative index of the tab to select
  96.      * @see #getCurrentPanelNdx
  97.      * @exception PropertyVetoException
  98.      * if the specified property value is unacceptable
  99.      */
  100.     public void setCurrentPanelNdx(int index) throws PropertyVetoException
  101.     {
  102.         if(index != curIndex)
  103.         {
  104.             Integer oldindex = new Integer(curIndex);
  105.             Integer newindex = new Integer(index);
  106.  
  107.             vetos.fireVetoableChange("CurrentPanelNdx", oldindex, newindex);
  108.             showTabPanel(index);
  109.  
  110.             // If we aren't designing, set current index even if the panel hasn't been
  111.             // added yet (we'll switch to it in add())
  112.             if (! java.beans.Beans.isDesignTime())
  113.                 curIndex = index;
  114.  
  115.             changes.firePropertyChange("CurrentPanelNdx", oldindex, newindex);
  116.         }
  117.     }
  118.  
  119.     /**
  120.      * Sets the tab labels associated with the panel positions.
  121.      * Note that the panels do not need to have been added yet for
  122.      * this method to work.
  123.      * @param sLabels an array of tab labels for the panel positions
  124.      * @see #getPanelLabels
  125.      * @exception PropertyVetoException
  126.      * if the specified property value is unacceptable
  127.      */
  128.     public void setPanelLabels(String[] sLabels) throws PropertyVetoException
  129.     {
  130.         String[] oldLabels = labels;
  131.  
  132.         vetos.fireVetoableChange("PanelLabels", oldLabels, sLabels);
  133.  
  134.         labels=sLabels;
  135.         updatePanelLabels();
  136.  
  137.         changes.firePropertyChange("PanelLabels", oldLabels, sLabels);
  138.     }
  139.  
  140.     /**
  141.      * Gets the current tab labels associated with the panel positions.
  142.      * @return an array of tab labels for the panel positions
  143.      * @see #setPanelLabels
  144.      */
  145.     public String[] getPanelLabels()
  146.     {
  147.         return labels;
  148.     }
  149.  
  150.     /**
  151.      * Sets the tab label  associated with the current panels at the given index.
  152.      * @param String newLabel the label to use for the tab at the given index.
  153.      * @param int labelIndex an index in the array of tab labels for the current panels.
  154.      * @see getPanelLabel
  155.      * @exception PropertyVetoException
  156.      * if the specified property value is unacceptable
  157.      */
  158.     public void setPanelLabel(String newLabel, int labelIndex) throws PropertyVetoException
  159.     {
  160.  
  161.         if(labelIndex >= 0 && labelIndex < labels.length && labels[labelIndex] != newLabel)
  162.         {
  163.             String oldLabel = labels[labelIndex];
  164.             vetos.fireVetoableChange("PanelLabel", oldLabel, newLabel);
  165.  
  166.             labels[labelIndex] = newLabel;
  167.             updatePanelLabels();
  168.  
  169.             changes.firePropertyChange("PanelLabel", oldLabel, newLabel);
  170.         }
  171.  
  172.     }
  173.  
  174.     /**
  175.      * Gets the current tab label associated with the current panels at the given index.
  176.      * @param int labelIndex an index in the array of tab labels for the current panels.
  177.      * @return String the label of the panel at the given index. Null if the index is out of range.
  178.      * @see setPanelLabel
  179.      */
  180.     public String getPanelLabel(int labelIndex)
  181.     {
  182.         if(labelIndex >= 0 && labelIndex < labels.length)
  183.         {
  184.             return labels[labelIndex];
  185.         }
  186.         else
  187.             return null;
  188.     }
  189.  
  190.     /**
  191.      * Puts the tabs on the top or bottom of the dialog.
  192.      * @param bTabsOnBottom if true the tabs are placed at the bottom of the
  193.      * dialog, if false on top
  194.      * @see #getTabsOnBottom
  195.      * @exception PropertyVetoException
  196.      * if the specified property value is unacceptable
  197.      */
  198.     public void setTabsOnBottom(boolean bTabsOnBottom) throws PropertyVetoException
  199.     {
  200.         Boolean oldValue = new Boolean(getTabsOnBottom());
  201.         Boolean newValue = new Boolean(bTabsOnBottom);
  202.  
  203.         if(!oldValue.equals(newValue))
  204.         {
  205.             vetos.fireVetoableChange("TabsOnBottom", oldValue, newValue);
  206.  
  207.             setTabsInfo(bTabsOnBottom ? BOTTOM : TOP, bTabsOnBottom ? SQUARE : ROUNDED);
  208.             layout();
  209.  
  210.             changes.firePropertyChange("TabsOnBottom", oldValue, newValue);
  211.         }
  212.     }
  213.  
  214.     /**
  215.      * Gets whether the tabs are at the bottom of the dialog.
  216.      * @return true if the tabs are at the bottom of the dialog, false if
  217.      * they are at the top
  218.      * @see #setTabsOnBottom
  219.      */
  220.     public boolean isTabsOnBottom()
  221.     {
  222.          return getTabsPosition()==TOP ? false : true;
  223.     }
  224.  
  225.     /**
  226.      * @deprecated
  227.      * @see #isTabsOnBottom()
  228.      */
  229.     public boolean getTabsOnBottom()
  230.     {
  231.          return isTabsOnBottom();
  232.     }
  233.  
  234.     /**
  235.      * Replaces a tab and its associated panel at the index specified.
  236.      * If it is desired to only change the label, use the base class
  237.      * BaseTabbedPanel's method setTab(String sLabel, boolean bEnabled, int index).
  238.      * @param sLabel the new tab label
  239.      * @param bEnabled enable the tab or not
  240.      * @param panel the new panel
  241.      * @param index the zero-relative index of the tab to change
  242.      * @see BaseTabbedPanel#setTab
  243.      * @see #getTabPanel
  244.      * @exception PropertyVetoException
  245.      * if the specified property value is unacceptable
  246.      */
  247.     public synchronized void setTabPanel(String sLabel, boolean bEnabled, Component panel, int index) throws PropertyVetoException
  248.     {
  249.         if ((index < 0) || (index >= vPanels.size()))
  250.             return;
  251.  
  252.         if (index == getCurrentTab() && !bEnabled)
  253.             return;
  254.  
  255.         try
  256.         {
  257.             Component oldPanel = (Component) vPanels.elementAt(index);
  258.             vetos.fireVetoableChange("TabPanel", oldPanel, panel);
  259.  
  260.             vPanels.setElementAt(panel, index);
  261.             setTab(sLabel, bEnabled, index);
  262.  
  263.             changes.firePropertyChange("TabPanel", oldPanel, panel);
  264.         }
  265.         catch (ArrayIndexOutOfBoundsException e) {}
  266.  
  267.     }
  268.  
  269.     /**
  270.      * Gets the panel for the tab at the given index.
  271.      * @param index zero-relative index of the tab
  272.      * @return returns the Panel associated with the tab
  273.      * @see #setTabPanel
  274.      */
  275.     public synchronized Component getTabPanel(int index)
  276.     {
  277.         if ((index < 0) || (index >= vPanels.size()))
  278.             return null;
  279.  
  280.         Component p = null;
  281.         try
  282.         {
  283.             p =  (Component)vPanels.elementAt(index);
  284.         }
  285.         catch (ArrayIndexOutOfBoundsException e) {}
  286.  
  287.         return p;
  288.     }
  289.  
  290.     /**
  291.      * Gets the index for a specific panel.
  292.      * @param panel the panel to get the index of
  293.      * @return the zero-relative index of the panel or -1 if it is not found
  294.      */
  295.     public synchronized int getPanelTabIndex(Component panel)
  296.     {
  297.         return vPanels.indexOf(panel);
  298.     }
  299.  
  300.     /**
  301.      * Selects the tab at the given index, showing it and its associated panel.
  302.      * The panel is activated, ready for user input.
  303.      * The tab position must be enabled.
  304.      * @param index zero-relative index of the tab to select
  305.      * @see #enableTabPanel
  306.      */
  307.     public synchronized void showTabPanel(int index)
  308.     {
  309.         if ( isEnabled(index) )
  310.         {
  311.             try
  312.             {
  313.                 Component p = (Component) vPanels.elementAt(index);
  314.                 setCurrentTab(index);
  315. //                if (bOsHack && p != null)
  316. //                {
  317. //                    p.hide();
  318. //                    setPanel(p);
  319. //                    p.show();
  320. //                }
  321. //                else
  322.                     showPanel(p);
  323.             }
  324.             catch (ArrayIndexOutOfBoundsException e) {}
  325.             catch (PropertyVetoException e) {}
  326.         }
  327.     }
  328.  
  329.     /**
  330.      * Appends a new tab and associated panel, which will be shown when the
  331.      * tab is selected. The tab/panel is added after the last existing
  332.      * panel.
  333.      * @param sLabel the tab label
  334.      * @param bEnabled enable the tab or not
  335.      * @param panel the panel to associate with the tab
  336.      * @return the zero-relative index of the newly added tab panel
  337.      */
  338.     public int addTabPanel(String sLabel, boolean bEnabled, Component panel)
  339.     {
  340.         return addTabPanel(sLabel, bEnabled, panel, -1);
  341.     }
  342.  
  343.     /**
  344.      * Adds a new tab and associated panel. The tab/panel is added at the
  345.      * specified index.
  346.      * @param sLabel the tab label
  347.      * @param bEnabled enable the tab or not
  348.      * @param panel the panel to associate with the tab
  349.      * @param pos the zero-relative index of the new tab panel
  350.      * @return the zero-relative index of the newly added tab panel
  351.      */
  352.     public int addTabPanel(String sLabel, boolean bEnabled, Component panel, int pos)
  353.     {
  354.         if (pos == -1)
  355.             vPanels.addElement(panel);
  356.         else
  357.             vPanels.insertElementAt(panel, pos);
  358.  
  359.         return addTab(sLabel, bEnabled, pos);
  360.     }
  361.  
  362.     /**
  363.      * Adds a component to the end of this container.
  364.      * This is a standard Java AWT method which gets called to add a
  365.      * component to a container. The specified component is added to
  366.      * the end of this container.
  367.      * <p>
  368.      * If the tab label for this position has not been set it is given
  369.      * the name "tab - #", where # is the zero-relative index of its
  370.      * position.
  371.      *
  372.      * @param comp the component to add
  373.      * @return the added component
  374.      * @see #remove
  375.      */
  376.     public Component add(Component comp) { return add(comp,-1); }
  377.  
  378.  
  379.     /**
  380.      * Adds a component to the end of this container.
  381.      * This is a standard Java AWT method which gets called to add a
  382.      * component to a container. Typically, the specified component is added to
  383.      * this container at the given zero-relative position index. A
  384.      * position index of -1 would append the component to the end.
  385.      * <p>
  386.      * It is overridden so that it only appends to the TabPanel.
  387.      * <p>
  388.      * If the tab label for this position has not been set it is given
  389.      * the name "tab - #", where # is the zero-relative index of its
  390.      * position.
  391.      *
  392.      * @param comp the component to add
  393.      * @param pos the zero-relative index at which to add the component or -1
  394.      * for end (IGNORED)
  395.      * @return the added component
  396.      * @see #remove
  397.      */
  398.     public synchronized Component add(Component comp, int pos)
  399.     {
  400.         boolean wasSuppressingRepaints = setSuppressRepaints(true);
  401.  
  402.         try
  403.         {
  404.             int newIndex = addTabPanel(createDefaultLabel(vPanels.size()),true,comp,pos);
  405.  
  406.             // If this is the panel that we've set to be the default, or we're designing,
  407.             // go ahead and switch to the new panel.
  408.             if (newIndex == curIndex || java.beans.Beans.isDesignTime())
  409.                 showTabPanel(newIndex);
  410.             updatePanelLabels();
  411.         }
  412.         finally
  413.         {
  414.             setSuppressRepaints(wasSuppressingRepaints);
  415.         }
  416.  
  417.         triggerRepaint();
  418.  
  419.         return comp;
  420.     }
  421.  
  422.     /**
  423.      * Takes no action.
  424.      * This is a standard Java AWT method which gets called to add a
  425.      * component to a container.
  426.      * It is overridden here to do nothing, so the user cannot change the way
  427.      * this container works.
  428.      *
  429.      * @param name the positioning directive for the layout manager (IGNORED)
  430.      * @param comp the component to add (IGNORED)
  431.      * @return the component parameter
  432.      */
  433.     public synchronized Component add(String name, Component comp) { return comp; }
  434.  
  435.     /**
  436.      * Removes the specified component from this container.
  437.      * This is a standard Java AWT method which gets called to remove a
  438.      * component from a container. When this happens the component's
  439.      * removeNotify() will also get called to indicate component removal.
  440.      *
  441.      * @param comp the component to remove
  442.      * @see symantec.itools.awt.BaseTabbedPanel#removeAll
  443.      * @see #add
  444.      */
  445.     public synchronized void remove(Component comp)
  446.     {
  447.         int i=getPanelTabIndex(comp);
  448.  
  449.         if (countTabs()==1)
  450.             removeAllTabPanels();
  451.         else
  452.         {
  453.             if (i==0)
  454.                 showTabPanel(1);
  455.             else
  456.                 showTabPanel(i-1);
  457.             removeTabPanel(i);
  458.         }
  459.     }
  460.  
  461.  
  462.     /**
  463.      * This routine re-sets all the tab labels using the latest string array
  464.      * provided in setPanelLabels().
  465.      * It is not typically called directly.
  466.      * @see #setPanelLabels
  467.      */
  468.     public void updatePanelLabels()
  469.     {
  470.         try
  471.         {
  472.             for (int i=0;i<vPanels.size();i++)
  473.             {
  474.                 String newlabel;
  475.                 if (labels!=null)
  476.                 {
  477.                     try
  478.                     {
  479.                         newlabel=labels[i];
  480.                     }
  481.                     catch (ArrayIndexOutOfBoundsException e)
  482.                     {
  483.                         newlabel=createDefaultLabel(i);
  484.                     }
  485.                 }
  486.                 else
  487.                     newlabel=createDefaultLabel(i);
  488.                 setLabel(newlabel,i);
  489.             }
  490.         }
  491.         catch(Throwable thr) {}
  492.     }
  493.  
  494.  
  495.     /**
  496.      * Conditionally enables a tab and its associated panel at the given index.
  497.      * The currently active tab cannot be disabled.
  498.      * @param bEnable true to enable, false to disable
  499.      * @param index the zero-relative index of the tab
  500.      * @exception PropertyVetoException
  501.      * if the specified property value is unacceptable
  502.      */
  503.     public synchronized void enableTabPanel(boolean bEnable, int index) throws PropertyVetoException
  504.     {
  505.         // ??? LAB ??? 05/07/97 Shouldn't this become an ambient property?
  506.         if ((index < 0) || (index >= vPanels.size()) || index == curIndex)
  507.             return;
  508.  
  509.         setEnabled(bEnable, index);
  510.     }
  511.  
  512.     /**
  513.      * Inserts a tab panel based on index.
  514.      * @param sLabel Label of the new tab to insert
  515.      * @param bEnabled If the new tab is enabled or not
  516.      * @param panel The panel to insert
  517.      * @param index zero-relative index at which the tab panel will be inserted.
  518.      */
  519.     public synchronized void insertTabPanel(String sLabel, boolean bEnabled, Component panel, int index)
  520.     {
  521.         if ((index < 0) || (index >= vPanels.size()))
  522.             return;
  523.  
  524.         if (index == getCurrentTab() && !bEnabled)
  525.             return;
  526.  
  527.         try
  528.         {
  529.             vPanels.insertElementAt(panel, index);
  530.             insertTab(sLabel, bEnabled, index);
  531.         }
  532.         catch (ArrayIndexOutOfBoundsException e) {}
  533.     }
  534.  
  535.     /**
  536.      * Removes a tab and its associated panel at the given index.
  537.      * The currently active tab cannot be removed.
  538.      * @param index zero-relative index of the tab
  539.      */
  540.     public synchronized void removeTabPanel(int index)
  541.     {
  542.         if ((index < 0) || (index >= vPanels.size()) || index == curIndex)
  543.             return;
  544.  
  545.         try
  546.         {
  547.             Component p = (Component) vPanels.elementAt(index);
  548.             super.remove(p);
  549.             vPanels.removeElementAt(index);
  550.         }
  551.         catch (ArrayIndexOutOfBoundsException e) {}
  552.  
  553.         removeTab(index);
  554.     }
  555.  
  556.     /**
  557.      * Removes all tabs and their associated panels, clearing the TabPanel entirely.
  558.      */
  559.     public synchronized void removeAllTabPanels()
  560.     {
  561.         vPanels = new Vector();
  562.         curIndex = -1;
  563.         removeAllTabs();
  564.     }
  565.  
  566.     /**
  567.      * Gets the number of tab panels in the TabPanel.
  568.      * @return the number of tab panels currently in the TabPanel
  569.      */
  570.     public int countTabs()
  571.     {
  572.         return vPanels.size();
  573.     }
  574.  
  575.        /**
  576.      * Returns the recommended dimensions to properly display this component.
  577.      * This is a standard Java AWT method which gets called to determine
  578.      * the recommended size of this component.
  579.      * <p>
  580.      * The returned size is large enough to display the biggest tab panel
  581.      * at its preferred size.
  582.      *
  583.      * @see #getMinimumSize
  584.      */
  585.     public Dimension getPreferredSize()
  586.     {
  587.         Dimension p = size();
  588.         Dimension m = getMinimumSize();
  589.         return new Dimension(Math.max(p.width, m.width), Math.max(p.height, m.height));
  590.     }
  591.  
  592.     /**
  593.      * Returns the minimum dimensions to properly display this component.
  594.      * This is a standard Java AWT method which gets called to determine
  595.      * the minimum size of this component.
  596.      * <p>
  597.      *
  598.      * @see #getPreferredSize
  599.      */
  600.     public Dimension getMinimumSize()
  601.     {
  602.         return new Dimension(20, 40);
  603.     }
  604.  
  605.     /**
  606.      * Adds a listener for all event changes.
  607.      * @param listener the listener to add.
  608.      * @see #removePropertyChangeListener
  609.      */
  610.     public synchronized void addPropertyChangeListener(PropertyChangeListener listener)
  611.     {
  612.         super.addPropertyChangeListener(listener);
  613.         changes.addPropertyChangeListener(listener);
  614.     }
  615.  
  616.     /**
  617.      * Removes a listener for all event changes.
  618.      * @param listener the listener to remove.
  619.      * @see #addPropertyChangeListener
  620.      */
  621.     public synchronized void removePropertyChangeListener(PropertyChangeListener listener)
  622.     {
  623.         super.removePropertyChangeListener(listener);
  624.         changes.removePropertyChangeListener(listener);
  625.     }
  626.  
  627.     /**
  628.      * Adds a vetoable listener for all event changes.
  629.      * @param listener the listener to add.
  630.      * @see #removeVetoableChangeListener
  631.      */
  632.     public synchronized void addVetoableChangeListener(VetoableChangeListener listener)
  633.     {
  634.          super.addVetoableChangeListener(listener);
  635.         vetos.addVetoableChangeListener(listener);
  636.     }
  637.  
  638.     /**
  639.      * Removes a vetoable listener for all event changes.
  640.      * @param listener the listener to remove.
  641.      * @see #addVetoableChangeListener
  642.      */
  643.     public synchronized void removeVetoableChangeListener(VetoableChangeListener listener)
  644.     {
  645.         super.removeVetoableChangeListener(listener);
  646.         vetos.removeVetoableChangeListener(listener);
  647.     }
  648.  
  649.     /**
  650.      * This is the PropertyChange Event handling innerclass.
  651.      */
  652.     class PropertyChange implements java.beans.PropertyChangeListener, java.io.Serializable
  653.     {
  654.         public void propertyChange(PropertyChangeEvent e)
  655.         {
  656.             showTabPanel(((Integer)e.getNewValue()).intValue());
  657.         }
  658.     }
  659.  
  660.     /**
  661.      * Creates a default name for a tab.
  662.      * @param int i Number to display as part of the tab's label.
  663.      * @return String The name to use for the new label.
  664.      * @see add(Component comp, int pos)
  665.      * @see updatePanelLabels()
  666.      */
  667.     private String createDefaultLabel(int i)
  668.     {
  669.         String name="tab - ";
  670.         name += String.valueOf(i);
  671.         return name;
  672.     }
  673.  
  674.     private PropertyChange myPropertyChangeHandler = new PropertyChange();
  675.     private symantec.itools.beans.VetoableChangeSupport vetos = new symantec.itools.beans.VetoableChangeSupport(this);
  676.     private symantec.itools.beans.PropertyChangeSupport changes = new symantec.itools.beans.PropertyChangeSupport(this);
  677.     Vector vPanels;
  678.  
  679.     String[] labels = null;
  680.  
  681.     transient boolean bOsHack;
  682. }
  683.